﻿using System;
using System.IO;

namespace SceneUnpacker.ScanDirectoryDemo
{
    public class ScanDirectory
    {
        private const string _patternAllFiles = "*.*";
        private string _searchPattern;

        public event DirectoryEventHandler DirectoryEvent;

        public event FileEventHandler FileEvent;

        public virtual bool ProcessDirectory(DirectoryInfo directoryInfo, ScanDirectoryAction action)
        {
            if (this.DirectoryEvent != null)
            {
                return this.RaiseDirectoryEvent(directoryInfo, action);
            }
            return true;
        }

        public virtual bool ProcessFile(FileInfo fileInfo)
        {
            if (this.FileEvent != null)
            {
                this.RaiseFileEvent(fileInfo);
            }
            return true;
        }

        private bool RaiseDirectoryEvent(DirectoryInfo directory, ScanDirectoryAction action)
        {
            bool flag = true;
            if (this.FileEvent != null)
            {
                DirectoryEventArgs e = new DirectoryEventArgs(directory, action);
                this.DirectoryEvent(this, e);
                flag = !e.Cancel;
            }
            return flag;
        }

        private bool RaiseFileEvent(FileInfo fileInfo)
        {
            FileEventArgs e = new FileEventArgs(fileInfo);
            this.FileEvent(this, e);
            return !e.Cancel;
        }

        private bool WalkDirectories(DirectoryInfo directory)
        {
            bool flag = true;
            if (flag = this.ProcessDirectory(directory, ScanDirectoryAction.Enter))
            {
                if (this.FileEvent != null)
                {
                    flag = this.WalkFilesInDirectory(directory);
                }
                if (flag)
                {
                    foreach (DirectoryInfo info in directory.GetDirectories())
                    {
                        if (((info.Attributes & FileAttributes.ReparsePoint) == 0) && !(flag = this.WalkDirectory(info)))
                        {
                            break;
                        }
                    }
                }
                if (flag)
                {
                    flag = this.ProcessDirectory(directory, ScanDirectoryAction.Leave);
                }
            }
            return flag;
        }

        public bool WalkDirectory(DirectoryInfo directory)
        {
            if (directory == null)
            {
                throw new ArgumentNullException("directory");
            }
            return this.WalkDirectories(directory);
        }

        public bool WalkDirectory(string path)
        {
            if ((path == null) || (path.Length == 0))
            {
                throw new ArgumentNullException("path");
            }
            return this.WalkDirectory(new DirectoryInfo(path));
        }

        private bool WalkFilesInDirectory(DirectoryInfo directory)
        {
            bool flag = true;
            foreach (string str in this._searchPattern.Split(new char[] { ';' }))
            {
                if (!flag)
                {
                    return flag;
                }
                foreach (FileInfo info in directory.GetFiles(str))
                {
                    if (!(flag = this.ProcessFile(info)))
                    {
                        break;
                    }
                }
            }
            return flag;
        }

        public string SearchPattern
        {
            get
            {
                return this._searchPattern;
            }
            set
            {
                if ((value == null) || (value.Trim().Length == 0))
                {
                    this._searchPattern = "*.*";
                }
                else
                {
                    this._searchPattern = value;
                    this._searchPattern = this._searchPattern.TrimEnd(new char[] { ';' });
                }
            }
        }

        public delegate void DirectoryEventHandler(object sender, DirectoryEventArgs e);

        public delegate void FileEventHandler(object sender, FileEventArgs e);
    }
}

